﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.Support.Constants;

namespace MS.InformationManagement.Support
{
    public class CamlHelper
    {
        public static string CreateCAMLQuery(string[] valores_campos, string[] nombre_campos, string[] types, string[] operations, ref string cadena)
        {
            StringBuilder sb = new StringBuilder();

            if (valores_campos.Length == 0)
            {
                return "<Query />";
            }

            if (valores_campos.Length <= 2)
            {
                for (int i = 0; i < valores_campos.Length; i++)
                {
                    AppendEQ(sb, valores_campos[i], nombre_campos[i], types[i], operations[i]);
                }
            }

            if (valores_campos.Length == 4)
            {
                for (int i = 0; i < valores_campos.Length; i++)
                {
                    if (i == 0 || i == 2) sb.Append("<And>");
                    AppendEQ(sb, valores_campos[i], nombre_campos[i], types[i], operations[i]);
                    if (i == 1 || i == 3) sb.Append("</And>");
                }
            }

            if (valores_campos.Length == 3)
            {
                for (int i = 0; i < valores_campos.Length; i++)
                {
                    if (i == 1) sb.Append("<And>");
                    AppendEQ(sb, valores_campos[i], nombre_campos[i], types[i], operations[i]);
                    if (i == 2) sb.Append("</And>");
                }
            }

            if (valores_campos.Length == 5)
            {
                for (int i = 0; i < valores_campos.Length; i++)
                {
                    if (i == 1 || i == 2 || i == 3) sb.Append("<And>");
                    AppendEQ(sb, valores_campos[i], nombre_campos[i], types[i], operations[i]);
                    if (i == 4) sb.Append("</And></And></And>");
                }
            }

            if (valores_campos.Length == 1)
            {
                sb.Insert(0, "<Where>");
                sb.Append("</Where>");
            }
            else
            {
                sb.Insert(0, "<Where><And>");
                sb.Append("</And></Where>");
            }

            cadena = sb.ToString();

            return cadena;
        }

        private static void AppendEQ(StringBuilder sb, string value, string field, string type, string operation)
        {
            // put your field's internal name in place of Category
            switch (operation.ToLower())
            {
                case "in": sb.Append(getInFilters(field, value));
                    break;
                case "userid": sb.Append(getUserFilter(field, value));
                    break;
                default : sb.Append(getStandarFilter(field,operation,type,value));
                    break;
            }
        }

        private static string getInFilters(string field,string searchItems)
        {
            var childs= searchItems.Split(',').ToList();
            StringBuilder sb = new StringBuilder()
            .Append("<In>")
            .Append(string.Format("<FieldRef Name='{0}' />", field))
            .Append("<Values>");
            foreach (var child in childs)
            {
                sb.Append(string.Format("<Value Type='Text'>{0}</Value>", child));
            }
            sb.Append("</Values>")
            .Append("</In>");
            return sb.ToString();
        }

        private static string getUserFilter(string field, string searchValue)
        {
            return string.Format(@"<Eq>
                                    <FieldRef Name='{0}' LookupId='True' />
                                    <Value Type='Integer'>{1}</Value>
                                   </Eq>",field, searchValue);
        }

        private static string getStandarFilter(string field, string operation, string type, string value)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<" + operation + ">");
            sb.Append("<FieldRef Name='" + field + "' />");
            sb.AppendFormat("<Value Type='" + type + "'>{0}</Value>", value);
            sb.Append("</" + operation + ">");
            return sb.ToString();
        }

    }
}
